﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Mighty.Common;
using System.Collections;
namespace Mighty.Brain
{
    public class HaeChoBrain :BasicBrain
    {
        List<HandedCard> SpadeCard = null;
        List<HandedCard> CloverCard = null;
        List<HandedCard> HeartCard = null;
        List<HandedCard> DiamondCard = null;

        bool Mighty;
        bool Joker;
        bool Jokercall;

        // 배팅 전에 카드 무늬별로 분류하기
        public override void BettingReadyEvent()
        {
            SpadeCard = new List<HandedCard>();
            CloverCard = new List<HandedCard>();
            HeartCard = new List<HandedCard>();
            DiamondCard = new List<HandedCard>();

            Mighty = false;
            Joker = false;
            Jokercall = false;

            foreach (HandedCard hc in gameInfo.myCards)
            {
                switch (hc.shape)
                {
                    case Shape.Spade: SpadeCard.Add(hc);
                        break;
                    case Shape.Clover: CloverCard.Add(hc);
                        break;
                    case Shape.Heart: HeartCard.Add(hc);
                        break;
                    case Shape.Diamond: DiamondCard.Add(hc);
                        break;
                    case Shape.Joker: Joker = true;
                        break;
                }

                if (hc.shape == Shape.Spade && hc.number == 14) Mighty = true;
                if (hc.shape == Shape.Clover && hc.number == 3) Jokercall = true;

            }
             
        }

        public override Betting BettingTicEvent()
        {
            Betting betting = new Betting();        

            int JQKACount = 0;
            int bettingPossible = 13;

            betting.isPass = true;



            // 가장 많은 무늬를 찾아 낸다
            Giruda selectedShape = Giruda.Heart;
            int selectedCount = HeartCard.Count;
            List<HandedCard> tmpCard = new List<HandedCard>();

            if (CloverCard.Count > selectedCount)
            {
                selectedShape = Giruda.Clover;
                tmpCard = CloverCard;
                selectedCount = CloverCard.Count;
            }
            if (SpadeCard.Count > selectedCount)
            {
                selectedShape = Giruda.Spade;
                tmpCard = SpadeCard;
                selectedCount = SpadeCard.Count;
            }
            if (DiamondCard.Count > selectedCount)
            {
                selectedShape = Giruda.Diamond;
                tmpCard = DiamondCard;
                selectedCount = DiamondCard.Count;
            }
            betting.giruda = selectedShape;

            
            if (selectedCount >= 5)                                 // 같은 무늬가 5개 이상이면
            {
                foreach (HandedCard hc in tmpCard)
                {

                    if (hc.number >= 11)                            // J, Q, K, A의 개수 체크
                        JQKACount++;
                }

                if (JQKACount >= 3)
                {
                    if (Mighty) bettingPossible++;
                    if (Joker) bettingPossible++;

                    if (gameInfo.betting.limit > 0)
                    {
                        Betting prevBetting = gameInfo.bettingHistory[gameInfo.bettingHistory.Count - 1];
                        if (bettingPossible > prevBetting.limit)
                        {
                            betting.limit = prevBetting.limit+1;
                           betting.isPass = false;
                            return betting;
                        }
                    }
                    else
                    {
                        betting.limit = 13;
                        betting.isPass = false;
                        return betting;
                    }

                    
                }
            }
          

            betting.isPass = true;

            return betting;
        }


        //#
        //# 각각의 카드 점수를 매겨서 가장 쓸모없는 카드 골라내기
        //#
        public HandedCard minCardFinder (List<HandedCard> cards)
        {

            HandedCard minCard = null;                                  //가장 쓸모없는 카드 초기화


            minCard = cards[0]; 
            foreach (HandedCard hc in cards)
            {

                // 점수 비교 후 가장 작은 카드 찾기
                if (Score(minCard) > Score(hc))
                {
                    minCard = hc;
                }
                
            }

            return minCard;
        }

        //
        //
        //

        public int Score(Card card)
        {
            int cardScore = card.number;
            if (card.shape == (Shape)gameInfo.betting.giruda) cardScore *= 10;    // 카드 무늬가 기루다이면 * 10점
            if (card.shape == Shape.Joker) cardScore *= 50;                       // 카드 무늬가 조커이면 * 50점
            if (card == gameInfo.mighty) cardScore *= 100;                        // 카드 무늬가 마이티이면 * 100점

            return cardScore;
        }


        //#
        //# 각각의 카드 점수를 매겨서 가장 큰 카드 골라내기
        //#
        public HandedCard maxCardFinder(List<HandedCard> cards)
        {

            HandedCard maxCard = null;                                  //가장 큰 카드 초기화

            maxCard = cards[0];
            foreach (HandedCard hc in cards)
            {

                // 점수 비교 후 가장 큰 카드 찾기
                if (Score(maxCard) < Score(hc))
                {
                    maxCard = hc;
                }
            }

            return maxCard;
        }



        public override HandedCard[] ChoiceCardEvent()
        {
            List<HandedCard> inhand = new List<HandedCard>();               // 손에 들 패 - 맘에 드는 카드들
            List<HandedCard> recyclebin = new List<HandedCard>();           // 재활용통 - 맘에 안드는 카드들
            List<HandedCard> dustbin = new List<HandedCard>();              // 쓰레기통 - 완전 버릴 카드들
            HandedCard tmpCard = new HandedCard();


            // 재활용통에 넣을 카드 분리수거
            foreach (HandedCard hc in gameInfo.myCards)
            {
                if (hc == gameInfo.mighty) inhand.Add(hc);
                else if (hc.shape == Shape.Joker) inhand.Add(hc);
                else if(hc.shape == (Shape) gameInfo.betting.giruda) inhand.Add(hc);
                else if (hc.number == 14) inhand.Add(hc);
                else recyclebin.Add(hc);

            }

            // 쓰레기통에 넣을 패 결정하기
            if (inhand.Count == 10)
            {
                dustbin = recyclebin;
            }
            else if (inhand.Count < 10)                                          // inhand 카드가 10장보다 부족할 경우
            {
                for (int i = 0; i < 3; i++)
                {
                    tmpCard = minCardFinder(recyclebin);
                    dustbin.Add(tmpCard);
                    recyclebin.Remove(tmpCard);
                    // 점수 작은 카드는 쓰레기통에     
                }
            }
            else                                                            // inhand 카드가 10장보다 많을 경우
            {
                for (int i = 0; i < inhand.Count - 10; i++)
                {
                    tmpCard = minCardFinder(inhand);
                    dustbin.Add(tmpCard);
                    recyclebin.Remove(tmpCard);               // 점수 작은 카드는 쓰레기통에     
                }
            }

            // 쓰레기통에 있는 패 묻어버리기
            foreach (HandedCard hc in gameInfo.myCards)
            {
                if (dustbin.Contains(hc))                                
                    hc.cmdRemove = true;                                    // 묻어버리기
                else                                                           
                    hc.cmdRemove = false;                                   // 내 패로 삼기
            }


            return gameInfo.myCards;
            



        }
        
        public override FriendPlayer ChoiceFriendEvent()
        {
            FriendPlayer f = new FriendPlayer();

            if (Mighty == false)
            {
                f.howToSelect = FriendPlayer.HowToSelect.card;
                f.cardCondition = (Card) gameInfo.mighty;
                return f;
            }

            if (Mighty == true && Joker == false)
            {
                Card joker = new Card();
                joker.shape = Shape.Joker;
                f.howToSelect = FriendPlayer.HowToSelect.card;
                f.cardCondition = joker;
                return f;
            }

            f.howToSelect = FriendPlayer.HowToSelect.firstwin;
            
            return f;
        }

        public int CountPictureCard(RoundCard[] cards)
        {
            int count = 0;
            foreach(RoundCard rc in cards)
            {
                if (rc == null) break;
                if (rc.number >= 10)
                {
                    count++;
                }
            }

            return count;
            
        }
      
        public override HandedCard RoundTicEvent()
        {
           
            Round r = gameInfo.roundHistory[gameInfo.roundIdx];
            List<HandedCard> possibleCards = new List<HandedCard>();
            HandedCard highCard = new HandedCard();

            foreach (HandedCard card in gameInfo.myCards)
            {
                if (card.isPossible) possibleCards.Add(card);
            }

            // 내가 주공이라면
            if (gameInfo.attackPlayer.position == gameInfo.myInfo.position)
            {
                // 내가 선일 때
                if (r.cardStack[0] == null)
                {
                    return maxCardFinder(possibleCards);
                }
                //선이 아닐 때
                else
                {
                    foreach (RoundCard rc in r.cardStack)
                    {
                        highCard = maxCardFinder(possibleCards);
                        if (Score(rc) < Score(highCard))
                        {
                            return highCard;
                        }
                        else
                        {
                            return minCardFinder(possibleCards);
                        }
                    }
                }
            }
            else 
            {

                // 내가 선일 때fffffffffffffffffffffffffff
                if (r.cardStack[0] == null)
                {
                    if (gameInfo.roundIdx == 0 || highCard.shape == Shape.Joker)
                    {
                        possibleCards.Remove(highCard);
                        highCard = maxCardFinder(possibleCards);
                    }
                    //return minCardFinder(possibleCards);
                }
                //선이 아닐 때
                else
                {
                    foreach (RoundCard rc in r.cardStack)
                    {
                        highCard = maxCardFinder(possibleCards);
                        if (possibleCards.Count > 1 && CountPictureCard(r.cardStack) < 2)
                        {
                            if (highCard == gameInfo.mighty || highCard.shape == Shape.Joker)
                            {
                                possibleCards.Remove(highCard);
                                highCard = maxCardFinder(possibleCards);
                            }
                        }
                        if (Score(rc) < Score(highCard))
                        {
                            return highCard;
                        }
                        else
                        {
                            return minCardFinder(possibleCards);
                        }
                    }
                }



            }

            ArrayList possibledCards = new ArrayList();
            foreach (HandedCard card in gameInfo.myCards)
            {
                if (card.isPossible) possibledCards.Add(card);
            }

            Random random = new Random();
            int k = random.Next(possibledCards.Count);

            return (HandedCard)possibledCards[k];

        }
        
        

    }
}
